﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.IO;
using System.Security.Cryptography;

public partial class gbr
{
    public class FileReadPosition
    {
        public long SliceStart;
        public long SliceEnded;
        public long SliceLength;
        public long FileSize;
        public long BufferMapLength;
        public int BufferLength;
        public bool SliceSkipRest;
        private int iSlice0Based;
        public FileReadPosition(int iSlice1Based, int iSliceCount, string sFileName, long lBufferMapLen, int lBufferLen)
        {
            FileSize = new FileInfo(sFileName).Length;
            SliceSkipRest = false;
            iSlice0Based = iSlice1Based - 1;
            SliceStart = GetSliceStartValue(iSlice0Based, iSliceCount);
            SliceEnded = GetSliceStartValue(iSlice1Based, iSliceCount);
            SliceLength = SliceEnded - SliceStart;
            BufferMapLength = lBufferMapLen;
            BufferLength = lBufferLen;
        }
        protected long GetSliceStartValue(int iSlice, int iSliceCount)
        {
            if (iSlice > iSliceCount)
                throw new Exception("Slice out of range");
            if (iSlice == iSliceCount)
                return FileSize;
            return (iSlice * FileSize) / iSliceCount;
        }
        public long GetMapBufferSize(long lMapPosInFile)
        {
            long lMapBufferSize_Use = BufferMapLength;
            if (lMapPosInFile + lMapBufferSize_Use > FileSize)
                lMapBufferSize_Use = FileSize - lMapPosInFile;
            return lMapBufferSize_Use;
        }
        public int GetBufferSize(long lMapBufferSize_Use, long lMemoryPosInMap)
        {
            int iLen = BufferLength;
            if (lMemoryPosInMap + iLen > lMapBufferSize_Use)
                iLen = (int)(lMapBufferSize_Use - lMemoryPosInMap);
            return iLen;
        }
    }
    public static IEnumerator GetFilesFromFilter(string filter)
    {
        bool bRecurse = false;
        if (filter.Length > 2 && char.ToUpper(filter[filter.Length - 1]) == 'S' && filter[filter.Length - 2] == '/')
        { // Ends with '/s', recurse...
            filter = filter.Substring(0, filter.Length - 2).Trim();
            bRecurse = true;
        }
        string sPath = Path.GetDirectoryName(filter);
        string sSearch = filter;
        sSearch = sSearch.Remove(0, sPath.Length + 1);
        foreach (string sFileName in Directory.GetFiles(sPath, sSearch, bRecurse ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly))
            yield return sFileName;
    }
    public static IEnumerator GetFilesFromFilespec(string fileSpec)
    {
        foreach (string sFilter in fileSpec.Split("|".ToCharArray()))
        {
            IEnumerator i = GetFilesFromFilter(sFilter.Trim());
            while (i.MoveNext())
                yield return i.Current;
        }
    }
    public static long Hash_64(string s)
    {
        byte[] ba = new byte[s.Length];
        for (int i = 0; i < s.Length; i++)
            ba[i] = (byte)s[i];
        byte[] bHash = MD5.Create().ComputeHash(ba);
        return BitConverter.ToInt64(bHash, 0);
    }

}